/**
 * 
 */
package fr.sinno.wms.batch.step;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import fr.sinno.wms.batch.dao.CommandExportRepository;
import fr.sinno.wms.batch.dao.CommandeRepository;
import fr.sinno.wms.batch.model.ExportedCommand;
import fr.sinno.wms.batch.model.HeaderCommand;
import fr.sinno.wms.batch.model.LineCommand;
import fr.sinno.wms.batch.model.PurchaseOrder;
import fr.sinno.wms.batch.service.ExportService;
import fr.sinno.wms.batch.utils.ConvertManager;
import fr.sinno.wms.batch.utils.FilesManager;

/**
 * @author aelguezzar
 *
 */
@Service("csvWriterTasklet")
public class CsvWriterTasklet implements Tasklet {

	private static final Logger LOG = Logger.getLogger(CsvWriterTasklet.class);

	@Autowired
	private FilesManager filesManager;

	@Autowired
	private CommandeRepository commandRepo;
	
//	@Autowired
//	private CommandExportRepository exportRepository;

	@Autowired
	private ConvertManager convertManager;
	
	@Autowired
	private ExportService exportService;

	@Value("${batch.sor.repertory}")
	private String sorPath;

	@Value("${batch.sor.delay}")
	private String delay;

	@Override
	@SuppressWarnings("unchecked")
	public RepeatStatus execute(StepContribution contribution,
			ChunkContext chunkContext) throws Exception {

		List<ExportedCommand> allExport = (List<ExportedCommand>) chunkContext
		.getStepContext().getStepExecution().getJobExecution()
		.getExecutionContext().get("allExport");
		
		LOG.info("*********************************************************************************************************");
		LOG.info("DEBUT TRAITEMENT SOR SUPRESSION ");

		List<LineCommand> removedList = (List<LineCommand>) chunkContext
				.getStepContext().getStepExecution().getJobExecution()
				.getExecutionContext().get("removedList");
	
		
		Map<String, PurchaseOrder> removedMap = new HashMap<String, PurchaseOrder>();

		List<String> cleanList = new ArrayList<String>();
		for (LineCommand line : removedList) {
			String codeDocument = line.getCodeDocument();
			if(removedMap.containsKey(codeDocument)) {
				PurchaseOrder order = removedMap.get(codeDocument);
				order.getListCommand().add(line);
			} else {
				PurchaseOrder newOrder = new PurchaseOrder();
				List<HeaderCommand> headerList = commandRepo.findListHeaderCommandById(codeDocument);
				if (null != headerList && !headerList.isEmpty()) {
					HeaderCommand header = headerList.get(0);
					List<LineCommand> commandLines = new ArrayList<LineCommand>();
					commandLines.add(line);
	
					newOrder.setHeader(header);
					newOrder.setListCommand(commandLines);
	
					removedMap.put(codeDocument, newOrder);
				} else {
				    if (!cleanList.contains(codeDocument)) {
					LOG.warn("ENTETE INTROUVABLE POUR LA COMMANDE : " + codeDocument);
					cleanList.add(codeDocument);
				    }
				}
			}
		}

		StringBuffer removeBuffer = new StringBuffer();
		Iterator<String> it = removedMap.keySet().iterator();
		while (it.hasNext()) {
			String key = it.next();
			PurchaseOrder order = removedMap.get(key);

			removeBuffer.append(convertManager.convertHeaderCommandToString(order.getHeader(), order.getListCommand().size(), "B"));
//			for (LineCommand command : order.getListCommand()) {
//				removeBuffer.append(convertManager.convertLineCommandToString(command));
//			}
		}
		//SOR09yyyymmddhhmmss
		if (!removeBuffer.toString().trim().equals("")) {
			String fileNameSupp = sorPath + "SOR09" + convertManager.formatDate(new Date()) + ".txt";
			filesManager.writeSorFile(fileNameSupp, removeBuffer);
		}
		if (null != removedMap && removedMap.size() > 0) {
			LOG.info("NOMBRE DE COMMANDE(S) SUPPRIMEE(S) : " + removedMap.size());
		}
		
		LOG.info("FIN TRAITEMENT SOR SUPRESSION ");
		LOG.info("*********************************************************************************************************");

		// TEMPS ARRET ENTRE SOR SUPPRESSION ET SOR COMMANDES 
		Long delayBatch = Long.valueOf(delay);
		LOG.info("TEMPS D'ATTENTE ENTRE SOR SUPPRESSION ET SOR COMMANDES : " + delayBatch / 1000 + "(s)");
		Thread.sleep(delayBatch);		
		
		
		LOG.info("*********************************************************************************************************");
		LOG.info("DEBUT TRAITEMENT SOR09 ");

		// RECUPERER LA LISTE DU CONTEXTE
		List<LineCommand> commandList = (List<LineCommand>) chunkContext
				.getStepContext().getStepExecution().getJobExecution()
				.getExecutionContext().get("commandList");

		Map<String, PurchaseOrder> commandMap = new HashMap<String, PurchaseOrder>();

		for (LineCommand line : commandList) {
			String codeDocument = line.getCodeDocument();
			if(commandMap.containsKey(codeDocument)) {
				PurchaseOrder order = commandMap.get(codeDocument);
				order.getListCommand().add(line);
			} else {
				PurchaseOrder newOrder = new PurchaseOrder();
				List<HeaderCommand> headerList = commandRepo.findListHeaderCommandById(codeDocument);
				if (null != headerList && !headerList.isEmpty()) {
					HeaderCommand header = headerList.get(0);
					List<LineCommand> commandLines = new ArrayList<LineCommand>();
					commandLines.add(line);
	
					newOrder.setHeader(header);
					newOrder.setListCommand(commandLines);
	
					commandMap.put(codeDocument, newOrder);
				} else {
				    if (!cleanList.contains(codeDocument)) {
						LOG.warn("ENTETE INTROUVABLE POUR LA COMMANDE : " + codeDocument);
						cleanList.add(codeDocument);
					    }
					}
			}
		}

		StringBuffer sorBuffer = new StringBuffer();
		Iterator<String> iterator = commandMap.keySet().iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			PurchaseOrder order = commandMap.get(key);

			sorBuffer.append(convertManager.convertHeaderCommandToString(order.getHeader(), order.getListCommand().size(), "A"));
			for (LineCommand command : order.getListCommand()) {
				sorBuffer.append(convertManager.convertLineCommandToString(command));
			}
		}
		//SOR09yyyymmddhhmmss
		if (!sorBuffer.toString().trim().equals("")) {
			String fileName = sorPath + "SOR09" + convertManager.formatDate(new Date()) + ".txt";
			filesManager.writeSorFile(fileName, sorBuffer);
		}

		if (null != commandMap && commandMap.size() > 0) {
			LOG.info("NOMBRE DE COMMANDE(S) ENVOYEE(S) : " + commandMap.size());
		}

		LOG.info("FIN TRAITEMENT SOR09 ");
		LOG.info("*********************************************************************************************************");

		List<ExportedCommand> tempList = new ArrayList<ExportedCommand>();
		for (String tmp : cleanList) {
			for (ExportedCommand expCommand : allExport) {
				if (expCommand.getCodeDocument().equalsIgnoreCase(tmp)) {
					tempList.add(expCommand);
				}
			}
//		    exportRepository.deleteListCommandExported(tmp);
		}
		for (ExportedCommand exported : tempList) {
			allExport.remove(exported);
		}
		exportService.writeCommandeExport(allExport);
		
		LOG.info("####################################################################################");
		LOG.info("###################  FIN TRAITEMENT SOR ET BATCH  ##################################");
		LOG.info("####################################################################################");
		return RepeatStatus.FINISHED;
	}


}
